package top.waikin.mooc.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.waikin.mooc.admin.domain.AdminEditDto;
import top.waikin.mooc.admin.domain.AdminInfoDto;
import top.waikin.mooc.admin.service.AdminCacheService;
import top.waikin.mooc.admin.service.AdminRoleRelationService;
import top.waikin.mooc.admin.service.AdminService;
import top.waikin.mooc.admin.service.RoleService;
import top.waikin.mooc.common.api.ResultCode;
import top.waikin.mooc.common.exception.Asserts;
import top.waikin.mooc.common.service.SMSService;
import top.waikin.mooc.entity.Admin;
import top.waikin.mooc.entity.AdminRoleRelation;
import top.waikin.mooc.entity.Permission;
import top.waikin.mooc.entity.Role;
import top.waikin.mooc.mapper.AdminMapper;
import top.waikin.mooc.security.util.PrivilegeUtil;

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * 管理员 服务实现类
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {

    @Autowired
    AdminCacheService adminCacheService;

    @Autowired
    AdminRoleRelationService adminRoleRelationService;

    @Autowired
    RoleService roleService;

    @Autowired
    SMSService smsService;


    @Override
    public void login(String telephone, String password) {
        Admin admin = getByTelephone(telephone);
        if (ObjectUtil.isNull(admin)) {
            Asserts.fail("用户名不存在");
        }
        if (ObjectUtil.notEqual(admin.getPassword(), password)) {
            Asserts.fail("密码错误");
        }
        if (ObjectUtil.notEqual(admin.getStatus(), 1)) {
            Asserts.fail("该用户被禁用");
        }
        PrivilegeUtil.login(admin.getTelephone());
    }

    @Override
    public void loginByAuthCode(String telephone, String authCode) {
        if (ObjectUtil.notEqual(adminCacheService.getAuthCode(telephone), authCode)) {
            Asserts.fail("验证码错误");
        }
        Admin admin = getByTelephone(telephone);
        if (ObjectUtil.isNull(admin)) {
            Asserts.fail("用户未注册");
        }
        PrivilegeUtil.login(admin.getTelephone());
    }

    @Override
    public void register(String telephone, String password, String authCode) {
        if (ObjectUtil.notEqual(adminCacheService.getAuthCode(telephone), authCode)) {
            Asserts.fail("验证码错误");
        }
        // 数据库中查询手机号是否已被注册
        if (ObjectUtil.isNotNull(getByTelephone(telephone))) {
            Asserts.fail("手机号已被注册");
        }
        Admin admin = new Admin()
                .setTelephone(telephone)
                .setPassword(password)
                .setNickname("管理员" + RandomUtil.randomString(5))
                .setProfile("https://mooc-1258408218.cos.ap-guangzhou.myqcloud.com/profile.png")
                .setStatus(1);
        save(admin);
        PrivilegeUtil.login(admin.getTelephone());
    }

    @Override
    public void generateAuthCode(String telephone) {
        StringBuilder stringBuilder = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            stringBuilder.append(random.nextInt(10));
        }
        String authCode = stringBuilder.toString();
//        String authCode = "111111";
        smsService.sendAuthCode(telephone, authCode);
        adminCacheService.saveAuthCode(telephone, authCode);
    }

    @Override
    public void updatePassword(String telephone, String password, String authCode) {
        if (ObjectUtil.notEqual(adminCacheService.getAuthCode(telephone), authCode)) {
            Asserts.fail("验证码错误");
        }
        Admin admin = getByTelephone(telephone);
        if (ObjectUtil.isNull(admin)) {
            Asserts.fail("用户未注册");
        }
        admin.setPassword(password);
        updateById(admin);
        adminCacheService.deleteAdmin(admin.getTelephone());
    }

    @Override
    public void updateAdminInfo(AdminInfoDto adminInfoDto) {
        Admin currentAdmin = getCurrentAdmin();
        BeanUtil.copyProperties(adminInfoDto, currentAdmin);
        updateById(currentAdmin);
        adminCacheService.deleteAdmin(currentAdmin.getTelephone());
    }

    @Override
    public Admin getCurrentAdmin() {
        String telephone = (String) PrivilegeUtil.getLoginIdDefaultNull();
        if (ObjectUtil.isNull(telephone)) {
            Asserts.fail(ResultCode.UNAUTHORIZED);
        }
        return getByTelephone(telephone);
    }

    @Override
    public Admin getByTelephone(String telephone) {
        // 从缓存查找
        Admin admin = adminCacheService.getAdmin(telephone);
        if (ObjectUtil.isNotNull(admin)) {
            return admin;
        }
        // 从数据库查找
        Wrapper<Admin> wrapper = new LambdaQueryWrapper<Admin>()
                .eq(Admin::getTelephone, telephone);
        admin = getOne(wrapper);
        // 添加到缓存
        if (ObjectUtil.isNotNull(admin)) {
            adminCacheService.saveAdmin(admin);
        }
        return admin;
    }

    @Override
    public boolean update(Integer id, AdminEditDto adminEditDto) {
        Admin admin = new Admin();
        BeanUtil.copyProperties(adminEditDto, admin);
        admin.setId(id);
        boolean b = updateById(admin);
        adminCacheService.deleteAdmin(admin.getTelephone());
        return b;
    }

    @Override
    public IPage<Admin> page(Integer current, Integer size, String keyWord) {
        Wrapper<Admin> queryWrapper = new LambdaQueryWrapper<Admin>().like(ObjectUtil.isNotNull(keyWord), Admin::getTelephone, keyWord).or().like(ObjectUtil.isNotNull(keyWord), Admin::getNickname, keyWord);
        return page(new Page<>(current, size), queryWrapper);
    }

    @Override
    public boolean updateRole(Integer id, List<Integer> roleIds) {
        // 获取旧角色
        Wrapper<AdminRoleRelation> queryWrapper = new LambdaQueryWrapper<AdminRoleRelation>().eq(AdminRoleRelation::getAdminId, id);
        List<AdminRoleRelation> oldRoleList = adminRoleRelationService.list(queryWrapper);
        List<Integer> oldRoleIds = oldRoleList.stream().map(AdminRoleRelation::getRoleId).collect(Collectors.toList());

        // 互相的差集
        List<Integer> reduceRoleIds = CollectionUtil.subtractToList(oldRoleIds, roleIds);
        List<Integer> increaseRoleIds = CollectionUtil.subtractToList(roleIds, oldRoleIds);

        // 删除新角色没有但是旧角色有的关系
        if (CollectionUtil.isNotEmpty(reduceRoleIds)) {
            Wrapper<AdminRoleRelation> wrapper = new LambdaQueryWrapper<AdminRoleRelation>().eq(AdminRoleRelation::getAdminId, id).in(AdminRoleRelation::getRoleId, reduceRoleIds);
            adminRoleRelationService.remove(wrapper);
            // 更新拥有角色的管理员的数量
            roleService.decreaseAdminCount(reduceRoleIds);
        }

        // 创建旧角色没有但是新角色有的关系
        if (CollectionUtil.isNotEmpty(increaseRoleIds)) {
            List<AdminRoleRelation> adminRoleRelations = increaseRoleIds.stream().map(integer -> new AdminRoleRelation().setAdminId(id).setRoleId(integer)).collect(Collectors.toList());
            adminRoleRelationService.saveBatch(adminRoleRelations);
            roleService.increaseAdminCount(increaseRoleIds);
        }

        // 删除权限缓存
        adminCacheService.deletePermissionList(id);

        return true;


//        // 删除原来的关系
//        Wrapper<AdminRoleRelation> wrapper = new LambdaQueryWrapper<AdminRoleRelation>().eq(AdminRoleRelation::getAdminId, id);
//        boolean b = adminRoleRelationService.remove(wrapper);
//
//        // 建立新的关系
//        if (!CollectionUtil.isEmpty(roleIds)) {
//            ArrayList<AdminRoleRelation> adminRoleRelations = new ArrayList<>();
//            for (Integer roleId : roleIds) {
//                AdminRoleRelation adminRoleRelation = new AdminRoleRelation().setAdminId(id).setRoleId(roleId);
//                adminRoleRelations.add(adminRoleRelation);
//            }
//            boolean saveBatch = adminRoleRelationService.saveBatch(adminRoleRelations);
//            // 删除缓存
//            adminCacheService.deletePermissionList(id);
//            return saveBatch;
//        }
//        return b;
    }

    @Override
    public List<Role> getRoleList(Integer id) {
        return adminRoleRelationService.getRoleListByAdminId(id);
    }

    @Override
    public List<Permission> getPermissionList(Integer id) {
        // 从缓存中查找
        List<Permission> permissionList = adminCacheService.getPermissionList(id);
        if (CollectionUtil.isNotEmpty(permissionList)) {
            return permissionList;
        }
        // 从数据库中查找
        permissionList = adminRoleRelationService.getPermissionListByAdminId(id);
        // 添加到缓存
        adminCacheService.savePermissionList(id, permissionList);
        return permissionList;
    }


}
